package com.acwing.partition4;

import java.io.*;
import java.util.ArrayDeque;
import java.util.Deque;

/**
 * @author `RKC`
 * @date 2022/1/27 15:42
 */
public class AC395冗余路径 {

    private static final int N = 5010, M = 20010;
    private static int[] h = new int[N], e = new int[M], ne = new int[M];

    private static int n = 0, m = 0, idx = 0, timestamp = 0, dccCnt = 0;
    private static int[] dfn = new int[N], low = new int[N], dcc = new int[N], degree = new int[N];
    private static boolean[] isBridge = new boolean[M];
    private static Deque<Integer> stk = new ArrayDeque<>(N);

    private static final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    private static final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));

    public static void main(String[] args) throws IOException {
        String[] s = reader.readLine().split(" ");
        n = Integer.parseInt(s[0]);
        m = Integer.parseInt(s[1]);
        for (int i = 0; i <= n; i++) h[i] = -1;
        for (int i = 0; i < m; i++) {
            s = reader.readLine().split(" ");
            int a = Integer.parseInt(s[0]), b = Integer.parseInt(s[1]);
            add(a, b);
            add(b, a);
        }
        tarjan(1, -1);
        //计算双连通分量的出度，如果当前边是桥，则桥所连的点所在的双连通分量的度加1
        for (int i = 0; i < idx; i++) {
            if (isBridge[i]) {
                int v = e[i];
                degree[dcc[v]]++;
            }
        }
        //节点个数位n的无向连通图，设度为1的点有cnt个，则添加 (cnt+1)/2 下取整条边后可以成为一个双连通图
        //统计度为1的连通分量
        int cnt = 0;
        for (int i = 1; i <= dccCnt; i++) {
            if (degree[i] == 1) cnt++;
        }
        writer.write(((cnt + 1) / 2) + "\n");
        writer.flush();
    }

    private static void tarjan(int u, int inEdge) {
        dfn[u] = low[u] = ++timestamp;
        stk.addLast(u);
        for (int i = h[u]; i != -1; i = ne[i]) {
            int v = e[i];
            if (dfn[v] == 0) {
                tarjan(v, i);
                low[u] = Math.min(low[u], low[v]);
                if (dfn[u] < low[v]) {
                    isBridge[i] = isBridge[i ^ 1] = true;
                }
            } else if (i != (inEdge ^ 1)) {
                low[u] = Math.min(low[u], dfn[v]);
            }
        }
        if (dfn[u] == low[u]) {
            dccCnt++;
            int v = -1;
            do {
                v = stk.pollLast();
                dcc[v] = dccCnt;
            } while (u != v);
        }
    }

    private static void add(int a, int b) {
        e[idx] = b;
        ne[idx] = h[a];
        h[a] = idx++;
    }
}
